package com.algorithms;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import politic.Politica;
import politic.PoliticaAzar;
import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.TwitterException;
import twitter4j.User;
import utils.ListUtils;

public class Algorithm1 implements Recomendable, Comparator<ScoredUser> {

	private List<Integer> totalUsers = null;
	private int totalUserSize = 0;
	private Politica politicaActual = null;
	private Integer limiteListas;

	public Algorithm1(String user, String pass, Politica politica) {
		TwitterApi.setUser(user, pass);
		this.politicaActual = politica;
		this.limiteListas = -1;
	}

	public Algorithm1(Politica politica) {
		this.politicaActual = politica;
		this.limiteListas = -1;
	}

	public Algorithm1(Politica politica, Integer limiteListas) {
		this.politicaActual = politica;
		if (limiteListas.intValue() > 0) {
			this.limiteListas = limiteListas;
		} else {
			this.limiteListas = -1;
		}
	}

	public Integer getMenciones(Integer userId) {
		Integer cantMenciones = 0;
		User user = null;
		try {
			user = TwitterApi.showUser(userId);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return Integer.valueOf(0);
		}
		if(user == null) return Integer.valueOf(0);
		Query query = new Query("@" + user.getScreenName());
		query.setRpp(100);
		QueryResult result = null;
		try {
			result = TwitterApi.twitter.search(query);
		} catch (TwitterException e) {
			e.printStackTrace();
			return Integer.valueOf(0);
		}
		cantMenciones = result.getTweets().size();
		return cantMenciones;
	}

	public List<ScoredUser> converitLisToScoredUsers(List<Integer> list1) {
		List<ScoredUser> auxList = new ArrayList<ScoredUser>();
		int contador = 0;
		Double scoreUser = 0.0;
		for (Integer auxInteger : list1) {
			contador++;
			System.out.println("Calculando score del usuario numero " + contador + " de " + this.totalUserSize );
			scoreUser = this.getScore(auxInteger);
			System.out.println("ID USUARIO:" + auxInteger + " :  SCORE: " + scoreUser);
			System.out.println(new Date());
			auxList.add(new ScoredUser(auxInteger, scoreUser));
		}
		return auxList;
	}

	public List<ScoredUser> getRecommendedUsers() {

		// Seguidos del usuario
		List<Integer> seguidos = TwitterApi.getSeguidos();

		// Seguidores de los seguidos
		List<Integer> primerNivelList = new ArrayList<Integer>();
		for (Integer auxInteger : seguidos) {
			List<Integer> auxList = TwitterApi
					.getSeguidoresFromUser(auxInteger);
			if (auxList != null) {
				ListUtils.addElementsToListWithPolitic(primerNivelList,
						auxList, this.politicaActual);
			}
			if (this.limiteListas > 0
					&& primerNivelList.size() > this.limiteListas) {
				break;
			}
		}
		System.out.println("Tamaño de la primera lista de seguidores:" + primerNivelList.size());
		// Seguidores de los seguidores de los seguidos
		List<Integer> segundoNivel = new ArrayList<Integer>();
		for (Integer auxInteger : primerNivelList) {
			List<Integer> auxList = TwitterApi
					.getSeguidoresFromUser(auxInteger);
			if (auxList != null) {
				ListUtils.addElementsToListWithPolitic(segundoNivel, auxList,
						this.politicaActual);
			}
			if (this.limiteListas > 0
					&& segundoNivel.size() > this.limiteListas) {
				break;
			}
		}
		if(segundoNivel.size()>limiteListas){
			segundoNivel = segundoNivel.subList(0, limiteListas-1);
		}
		this.totalUsers = segundoNivel;
		this.totalUserSize = segundoNivel.size();
		System.out.println("Tamaño de la segunda lista de seguidores:" + this.totalUserSize);
		
		List<Integer> segundoNivelSinRepetidos = ListUtils
				.eliminarOcurrencias(segundoNivel);
		List<ScoredUser> segundoNivelSinRepetidoScored = this
				.converitLisToScoredUsers(segundoNivelSinRepetidos);
		Collections.sort(segundoNivelSinRepetidoScored, this);
		Collections.reverse(segundoNivelSinRepetidoScored);
		System.out.println("Temino todo!!!");

		for (ScoredUser su : segundoNivelSinRepetidoScored) {
			System.out.println(su.getId() + " " + su.getScore() + " ");
		}
		if(segundoNivelSinRepetidoScored.size()>20)
			return segundoNivelSinRepetidoScored.subList(0, 20);

		return segundoNivelSinRepetidoScored;
	}

	public Double getScore(Integer idUsuario) {
		Double score = 0.0;
		Double nroMenciones = 0.0;
		score = Double.valueOf(ListUtils.getOcurrencias(this.totalUsers,
				idUsuario))
				/ Double.valueOf(this.totalUserSize);
		nroMenciones = Double.valueOf(this.getMenciones(idUsuario)
				.doubleValue());
		if (nroMenciones.equals(0.0)) return 0.0;// Optimizacion, no tiene
		// sentido seguir, ya es 0
		score = score * nroMenciones;
		score = score / Double.valueOf(100.0);
		score = score
				* Double.valueOf(TwitterApi.getSeguidoresFromUser(idUsuario)
						.size());
		if (score.equals(0.0)) return 0.0;// Optimizacion, no tiene sentido

		// seguir, ya es 0
		double seguidosSize = Double.valueOf(TwitterApi.getSeguidos().size());

		if (seguidosSize > 0) score = score / seguidosSize;
		return score;
	}

	public static void main(String[] args) {

		/* new LoginApplication(); */
		Algorithm1 recomendable = new Algorithm1("fran_test", "franpass",
				new PoliticaAzar(0.1));

		// recomendable.getMenciones(16897);
		List<ScoredUser> recomendaciones = recomendable.getRecommendedUsers();
		for (ScoredUser auxInteger : recomendaciones) {
			System.out.println(auxInteger.getId());
		}
	}

	@Override
	public int compare(ScoredUser idUsuario1, ScoredUser idUsuario2) {
		try {
			Double score1 = idUsuario1.getScore();
			Double score2 = idUsuario2.getScore();

			if (score1 < score2) {
				return -1;
			}
			if (score1 > score2) {
				return 1;
			}
			return 0;
		} catch (Exception e) {

		}
		return 0;
	}
	//a ver si cambiaa
}
